
#include "Init.h"

#if defined(__CC_ARM)
//ARM CC

#define INIT_SECTION(level)	InitEntry ## level

#define SectionSymble(prefix, name, endfix)		prefix ## name ## endfix

#define Section_Init(name)	 do{	\
	extern unsigned int SectionSymble(Image$$, name, $$Base);	\
	extern unsigned int SectionSymble(Image$$, name, $$Limit);	\
	const InitEntry_T* start = (const InitEntry_T *)&SectionSymble(Image$$, name, $$Base);	\
	const InitEntry_T* end = (const InitEntry_T *)&SectionSymble(Image$$, name, $$Limit);	\
	Section_DoInit(start, end);		\
}while(0)
		
static void Section_DoInit(const InitEntry_T *start, const InitEntry_T *end){
	const InitEntry_T *initFunc = start;
	
	while(initFunc < end){
		if(*initFunc){
			(*initFunc)();
		}
		initFunc++;
	}
}

void Init(void){
	Section_Init(INIT_SECTION(0));
	Section_Init(INIT_SECTION(1));
	Section_Init(INIT_SECTION(2));
	Section_Init(INIT_SECTION(3));
}


#elif defined(__ICCARM__)

#define INIT_SECTION(level)	"InitEntry" # level

#pragma section = INIT_SECTION(0)
#pragma section = INIT_SECTION(1)
#pragma section = INIT_SECTION(2)
#pragma section = INIT_SECTION(3)

#define Section_Init(name)	\
	Section_DoInit((InitEntry_T *)__section_begin(name), (InitEntry_T *)__section_end(name))

static void Section_DoInit(const InitEntry_T *start, const InitEntry_T *end){
	const InitEntry_T *initFunc = start;
	
	while(initFunc < end){
		if(*initFunc){
			(*initFunc)();
		}
		initFunc++;
	}
}

void Init(void){
	Section_Init(INIT_SECTION(0));
	Section_Init(INIT_SECTION(1));
	Section_Init(INIT_SECTION(2));
	Section_Init(INIT_SECTION(3));
}

#else
#pragma section(".init$a")
__declspec(allocate(".init$a")) static const InitEntry_T __InitSegStart = (InitEntry_T)1;

#pragma section(".init$z")
__declspec(allocate(".init$z")) static const InitEntry_T __InitSegEnd = (InitEntry_T)1;


void Init(void) {
	const InitEntry_T *x = &__InitSegStart;

	for (++x; x < &__InitSegEnd; ++x)
		if (*x) (*x)();
}
#endif 



